package wwl.lsf.hellospringboot.xss;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.text.StringEscapeUtils;

/**
 * @Date:2019/5/6 18:59
 */
@Slf4j
public class CustomObjectMapper extends ObjectMapper {

    private static final long serialVersionUID = -3448961813323784217L;

    public CustomObjectMapper() {
        SimpleModule module = new SimpleModule("XssStringJsonSerializer");
        module.addSerializer(new JsonHtmlXssSerializer(String.class));
        //因为我需要用到入参原始的带有html的json所以我就不转了
//        module.addDeserializer(String.class, new JsonHtmlXssDeserializer(String.class));
        this.registerModule(module);
    }

    /**
     * 对出参的json进行转义
     */
    class JsonHtmlXssSerializer extends JsonSerializer<String> {

        public JsonHtmlXssSerializer(Class<String> string) {
            super();
        }

        @Override
        public Class<String> handledType() {
            return String.class;
        }

        @Override
        public void serialize(String value, JsonGenerator jsonGenerator,
            SerializerProvider serializerProvider) throws IOException {
            if (value != null) {
                String encodedValue = xssClean(value);
                jsonGenerator.writeString(encodedValue);
            }
        }
    }

    /**
     * 对入参的json进行转义
     */
    class JsonHtmlXssDeserializer extends JsonDeserializer<String> {

        public JsonHtmlXssDeserializer(Class<String> string) {
            super();
        }

        @Override
        public Class<String> handledType() {
            return String.class;
        }

        @Override
        public String deserialize(JsonParser jsonParser,
            DeserializationContext deserializationContext)
            throws IOException, JsonProcessingException {
            String value = jsonParser.getValueAsString();
            if (value != null) {
                return xssClean(value);
            }
            return value;
        }
    }

    private String xssClean(String value) {
        return StringEscapeUtils.escapeHtml4(value);
    }
}
